package com.tbit.uqbike.client.service.impl;

import cn.hutool.core.lang.Pair;
import com.tbit.common.constant.OperationPlatform;
import com.tbit.common.entity.UserOpLog;
import com.tbit.uqbike.client.business.user_op_log.service.UserOpLogService;
import com.tbit.uqbike.client.dao.core.CouponUserDao;
import com.tbit.uqbike.client.pojo.CouponUser;
import com.tbit.uqbike.client.pojo.CouponUserDto;
import com.tbit.uqbike.client.pojo.User;
import com.tbit.uqbike.client.service.CouponUserService;
import com.tbit.uqbike.client.service.UserService;
import com.tbit.uqbike.client.util.DateTimeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;

/**
 * @Author: chen
 * @Description: 优惠券用户绑定
 * @Date: 创建于 14:38 2020/1/4
 */
@Service("couponUserService")
public class CouponUserServiceImpl implements CouponUserService {
    @Autowired
    private CouponUserDao couponUserDao;
    @Autowired
    private UserOpLogService userOpLogService;
    @Autowired
    private UserService userService;

    @Override
    public List<CouponUserDto> getByUserId(Integer accountId, Integer userId) {
        Map<String, Object> map = new HashMap<>();
        map.put("accountId", accountId);
        map.put("userId", userId);
        List<CouponUserDto> list = couponUserDao.getByUserId(map);
        if (list.size() > 0) {
            for (CouponUserDto c : list) {
                if (DateTimeUtil.getTimeDF(c.getEndTime() + " 23:59:59", DateTimeUtil.getNowTime()) >= 0 && c.getIsValid() == 1) {
                    couponUserDao.updateUse(c.getCouponuserId());
                    c.setIsValid(0);
                }
            }
        }

        return list;
    }

    @Override
    public List<CouponUserDto> getMoneyCoupon(Integer accountId, Integer userId) {
        Map<String, Object> map = new HashMap<>();
        map.put("accountId", accountId);
        map.put("userId", userId);
        return couponUserDao.getMoneyCoupon(map);
    }

    @Override
    public void insert(CouponUser couponUser) {
        couponUser.setIsUse(0);
        couponUser.setRecTime(DateTimeUtil.getNowTime());
        couponUser.setIsValid(1);
        addBatch(Collections.singletonList(couponUser));
    }

    @Override
    public void edit(Integer couponuserId) {
        CouponUser cu = couponUserDao.getByCouponUserId(couponuserId);
        if (cu == null) {
            return;
        }

        couponUserDao.edit(couponuserId);

        // 插入用户操作日志
        User user = userService.getByUserId(cu.getUserId());
        userOpLogService.insertSingle(UserOpLog.builder()
                .accountId(user.getAccountId())
                .opUser(user.getName())
                .opUserPhone(user.getPhone())
                .targetUser(user.getName())
                .targetUserPhone(user.getPhone())
                .operation("优惠券变动")
                .opType("用户使用")
                .opPlatform(OperationPlatform.CLIENT.code)
                .opTime(LocalDateTime.now())
                .result(true)
                .detail("优惠券ID: " + cu.getCouponId())
                .build());
    }

    @Override
    public CouponUserDto getById(Integer accountId, Integer userId) {
        Map<String, Object> map = new HashMap<>();
        map.put("accountId", accountId);
        map.put("userId", userId);
        return couponUserDao.getById(map);
    }

    @Override
    public List<CouponUserDto> getByCouponType(Integer accountId, Integer userId) {
        Map<String, Object> map = new HashMap<>();
        map.put("accountId", accountId);
        map.put("userId", userId);
        return couponUserDao.getByCouponType(map);
    }

    @Override
    public void addBatch(List<CouponUser> list) {
        couponUserDao.addBatch(list);

        // 插入用户操作日志
        list.sort(Comparator.comparingInt(CouponUser::getUserId));
        Map<Integer, User> userMap = new HashMap<>();
        for (CouponUser c : list) {
            if (!userMap.containsKey(c.getUserId())) {
                userMap.put(c.getUserId(), userService.getByUserId(c.getUserId()));
            }
        }

        // couponId, userId -> count 计算每种优惠券数量，避免插入大量日志
        Map<Pair<Integer, Integer>, Integer> cntMap = new HashMap<>();
        for (CouponUser c : list) {
            Pair<Integer, Integer> key = Pair.of(c.getCouponId(), c.getUserId());
            cntMap.merge(key, 1, Integer::sum);
        }
        cntMap.forEach((cu, count) -> {
            User user = userMap.get(cu.getValue());
            userOpLogService.insertSingle(UserOpLog.builder()
                    .accountId(user.getAccountId())
                    .opUser(user.getName())
                    .opUserPhone(user.getPhone())
                    .targetUser(user.getName())
                    .targetUserPhone(user.getPhone())
                    .operation("优惠券变动")
                    .opType("发放")
                    .opPlatform(OperationPlatform.CLIENT.code)
                    .opTime(LocalDateTime.now())
                    .result(true)
                    .detail("优惠券ID: " + cu.getKey() + "\n优惠券数量: " + count)
                    .build());
        });
    }

    @Override
    public Boolean hasValidCoupon(Integer userId) {
        return couponUserDao.countValidCoupon(userId) > 0;
    }
}
